     _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
  .'-_v_v_v_v_v_v_v_v_v_v_v_v_v_v_v_-'.
 //                                   \\
 \\ C-64 BASIC Ten-Liner Contest 2020 //
 //                                   \\
 \\ Radagast's Flight from Dol Guldur //
 //                                   \\
 \\ (c) 2019 Maik Schallenberg 'pa1ny //
 // E-Mail: pa1ny @ gmx.de            \\
 \\                                   //
  `^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^
     


### Radagast's Racing Rhosgobel Rabbits ###
===========================================

This game was inspired by "Autobahn" from SFB-Computer-Club Part 2/5 German TV series.


### Intro & Story
====================
You are Radagast the Brown! Fleeing from Dol Guldur on your sleigh pulled by Rhosgobel Rabbits
through the dimmest of all dark forests, the Mirkwood full of spiders from Ungoliant herself.

The only save path through the Mirkwood is tricky and narrow sometimes. Most of the spiders
are outside that path, but some of them are not, so be careful all the time and avoid them!
The rabbits run like hell and they don't break. You can only guide your bunny sled slightly
to the left and right, hopefully not getting off the course or hitting a spider on your way.

With a little luck, you'll also find some green rings, that give you extra power and points.
Unfortunately, these gems are made from Celebrimbor and the Dark Lord Sauron, foster-son and
slave of Morgoth. His burning eye is watching you at all times and it hunts for all the Maiar
in Middle-Earth, especially the Istari and his will and wrath blinks up for a moment, whenever
you pick one of them up!

May the forc... uhmm, no. Seven blessin.. ehhh, still wrong..

Should Valar Manwe lead you on your holy path to Valinor ... yeah! That's it :)

(Note: If you're asking yourself what the hell I'm talking about, just read or watch something
       from J.R.R. Tolkien, especially "The Hobbit" Movie or "The Silmarillion" in this case)


### How To Start
===================
First choose your skill level! An integer value between 1 to 8 is recommended, but if you wanna see
some graphical nonsense, sick error messages or strange negative scores at the end, feel free to
enter the squareroot of Minus-Pi in there or whatever...

So when you finally entered a valid skill number and hit RETURN, the game is launched immediately!

Your Joystick or Gamepad in Port 2 can be used to avoid a crash or collecting rings by just turning
it left or right. You can also use both hands and press down (for left) and fire-button (for right)
on-the-fly as an alternative. That's possible because I used the signum function to peek the joystick
direction .. did anybody else ever used this in a ten-liner?
You may find this could be a quicker movement or more precise control. Sometimes keyboarders complain
about the pads and sticks for better reactions with two fingers what-so-ever.

That's it! When you finally crash (and you WILL) your score is shown, depending on the skill level
you've entered previously, the length / time you rode the path down and the rings you've picked up.

Try again with the same settings for another round and hunting highscores by pressing just FIRE button!

There's a glitch and bug-using is possible. For example just go for skill level 8 (not -8 .. and don't
say I didn't warn you!) and travel directly to the right to avoid the path and - if that isn't already
enough - even all spiders by driving down your sled at the very last column until infinity .. almost.

Needless to say this is ultra cheating and you will burn in hell forever! ^_^


### System Requirements
==========================
> Commodore 64 with BASIC V2 or compatible system / emulator on any other hardware
> Using WinVICE emulator, just drag and drop the "radagast.prg" into the window


### Inspiration, Motivation and Development
==============================================
This game was originally not planned as a 10-Liner, but I wanted to keep it short and simple just
from scratch. Pretty much like it was presented in the SFB-Computer-Club Part 2/5 German TV series.

In the end of 2019 I rediscovered the good old retro computers from my childhood, grazing youtube
clips from the 8-Bit-Guy, Commodore Promotions, vintage TV-Shows, etc. all day long.
Eventually I stumbled over the legendary German "WDR Computer Club" and also a mini series of the
"SFB-Computer-Club" where they were also doing some plain BASIC stuff and I was quite surprised
how fast I got back into the topic .. seems like it was all present and I didn't forget anything.

So I launched the WinVICE emulator on a modern PC to get the feeling again and tried out some
totally new ideas and possiblities I've never heard before in the old days without internet or
online communities containing a huge mass of information and tweaks.

Anyway the retro trend was still under way and I missed out so much. The C64-DTV was available for
years and a C-64 Mini version was released by retrogames.biz already. It was crystal clear then,
that I would buy The C-64 "Maxi" Version at Christmas 2019. The best gift for myself long-since!

So on Monday 23th December I was the first camper in front of the ONLY local Media-Markt here, that
announced to have the product "in stock" de facto and you can imagine my happy face when this turns
out to be true at last :)

With this quite nice replica of the orginal breadbox I started to go 100% C-64 (and even VIC-20!)
again, spending hours and hours in BASIC and collecting all the good old software & games back.

But the first programs did not cast Radagast or anything. To get back into the stuff, I decided to
do some complex calculations of Pi using even modern math formulas on that good old 8-bit machine.
I thought, that 8 decimal places of Pi shouldn't be that expensive and BASIC V2 isn't able to show
more anyway, but I had to realize it would sometimes be necessary to get back to the emulator and
use the warp mode to have some fast and reliable results.

For example, the convergence of the Wallis-Product and the Leibniz-Formula are way too slow, but
this goes kind of off-topic here. Let me just show you two results I'm pretty satisfied with for
all the math nerds & geeks out there:

0 q=0:d=4:m=4:n=3:o=4:p=3: rem leet pi
1 for i=1 to 1337 step2: q=q+d/i: d=-d
2 m=(m+q+d/i/2)/2: rem 1st average term
3 n=(n+m)/2:o=(o+n)/2:p=(p+o)/2:rem 2nd
4 print i,p: next: rem pi in 1337 speak

This will deliver the exact Pi (as variable p) that is stored in BASIC's ROM in 1337 double-steps.
The second one is a 1-Liner, that will do the same in just 27 steps (feat. Rabinowitz algorithm):

p=3:fOn=-27to-1:p=2-n/(-2*n+1)*p:?p:nE

Ok, that's enough mathematics so far I think .. back to topic now!

The game I planned should be easily readable and editable all the time. That was my individual
policy, the conditions I impose to myself. This means in effect a maximum of 24 lines with a
maximum of 39 characters each (on a C-64 screen).

The inspiring "Autobahn" from the SFB-Computer-Club can be fundamentally pressed into a 1-Liner
or let's say 2-Liner (to start it with some tolerable values) like this:

0?tAa)1tAb)0tAa+18)1:gEr:a=a+rN(.)*2-1:b=b+r-sG(r)*5:gO
a=9:b=18:gO

Okay, this is a VERY simple version, but you can even control it left and right in adjustable(!)
steps with the numbers on your C-64 keyboard (4=left, 6=right, 3=two-left, 7=two-right, etc.)

This one here represents a much more worthier implementation:

10 a=10 : b=19 : for p = . to 9999
20 print tab(a)")"tab(b)"v"tab(a+18)"("
30 g%=rnd(.)*3-1 : a=a+g% : get r$
40 if r$ then b=b+val(r$)-5
50 if a=0 or a=20 then a=a-g%
60 if a<b then if b<a+18 then next p

Fast forward a few weeks I added better layouts, a skill level plus score calculation, a little
explosion graphic in PETSCII, more colours, a few SID sounds, new obstacles aka snowflakes or
"spiders", a repositioning of the racer / sleigh in the center of the screen, joystick control,
even more real sound effects and screen shattering plus an ongoing game-over animation including
a quick restart feature in the end, that looks like this:

1 fori=.to97:poke53281-(iand1),i+i:next
2 input"SqskillZ1-8";s:poke214,24:a=9+s
3 b=1643:e=54273:pokee+5,99:pokee+3,129
4 c=29-s:k=56320:pokee+23,9:forp=.tok
5 f=rnd(.)*39:pokeb,65:ong+2goto6,7,8
6 printtab(a)"pUK"tab(c)"UKe":goto9
7 printtab(a)"pi>"tab(c)"B<Z":goto9
8 printtab(a)"piJI"tab(c)"iJI["
9 g=int(f/13-1):ifa+g=0orc+g=38theng=0
10 a=a+g:c=c+g:pokee,2+g:poke1984+f,42
11 r=peek(k)-127:ifrthenb=b-sgn(r+7)
12 ifpeek(b)=32thenpokee-1+b,9+g:next
13 poke214,14:poke211,b-1625:sys58640
14 print"x{|\_qiii\V}\qiii_\|qqqqqqqq"
15 fori=.to72:poke53270,i:pokee,72-i
16 next:print"^CCQ score:"p*s:d=111
17 poke214,rnd(1)*21:poke211,rnd(1)*32
18 poke646,rnd(.)*15+1:print"game-over"
19 fori=.tod:next:ifpeek(k)-dgoto17
20 sys58692:poke214,24:a=9+s:goto3

(copy-paste this in your C-64 emulator and correct the special characters as follows)

Cleanup Line 2: S=[Shift+Home],q=ArrowDown
Railway Line 6,7,8: p=[Tab+8], i=ArrowLeft,B=[Ctrl+Q]
Spiders Line 6,7,8: e=[Tab+2], Z=[Ctrl+7], [=[Ctrl+8]
Explode Line 14: x=[Ctrl+5], {=[Tab+9], |=[Shift+Ins], \=[Ctrl+], _=[Ctrl+~], }=[Tab+0]
Score Line 16: ^=[Tab+6]

This was the final version on New Year's Eve 2019 and I got some friends to betatest this 4 fun.
In this state, I can alternate the program anytime on the C-64 screen and add some more gimmicks
or features easily. There were some modifications and "special versions" in these days.

In January 2020 I first heard about the BASIC 10-Liner contest and read the rules. Using
command abbreviations and (over)doubled lines to press as much as possible into the rows was
not very convincingly for me at first sight, but I recognized soon that this is eventually
the lowest common denominator to start a contest of this kind that should really work.

So I began to convert my little racing game in the meaning of this regulations and learned a
lot about shortening IF-statements to numeric or boolean expressions or even converting them
completely to ON-statements to make the precious space behind THEN or GOTO usable again.


### Final 10-Liner Source Code & Explanations
================================================
                                                                                |
0e=54273:pOe+5,99:pOe+3,129:fOi=.to64:t=1-t:pOe+t-993,i:nE:input"skill1-8";s
1k=56320:pO214,24:pOe+23,9:f=1984:a=9+s:b=1643:c=29-s:fOp=.tok:l=g+2:onlgO2,3,4
2?tAa)""tAc)"":pOf+rN(.)*39,87:g=int(rN(.)*3-t):g=g-(-g=a):v=53272:gO5
3?tAa)">"tAc)"<":pOf+rN(.)*39,42:g=int(rN(.)*3-t):g=g-(-g=a)+(c+g=38):gO5
4?tAa)""tAc)"ɛ":pOf+rN(.)*39,42:g=int(rN(.)*3-t):g=g+(c+g=38):d=214:remi
5a=a+g:c=c+g:r=pE(k)-120:b=b+sG(r)*(r<7):ifpE(b)=32tHpOe,l:pOe-t+b,l+7:pOb,i:nE
6ifpE(b)=87tHpOe,d:pOv,96:pOv+8,t:q=q+9:pOb+g+360,83:pOb,.:pOv+8,l+t:pOv,21:nE
7pOd,13:?tAb-1625)"֒ߦ":fOj=.to72:pOv-2,j:pOe,72-j
8nE:?"CCQ score:"p*s+q:q=0:fOj=.tok:h=rN(.)*18+t:pO646,h+h:pO162,.:wA162,8
9?tAh)"ZXMVNLgame-overPNVMXZ":pOd,h:on-(pE(k)<>111)gO8:?"":gO1radagast's race
                                                                                |
(you can copy-paste this directly in WinVICE 2.2 with standard keyboard config)

Variables used:
a = astriction left
b = bob / racer / sleigh
c = circumscription right
d = direct jump into line
e = engine (SID highbyte)
f = flakes / spiders / rings
g = growth (trajectory -1/0/1)
h = hype message aka game-over
i = integer 4 loops & sled(65)
j = jnteger alternative (jerk)
k = knueppel (Joystick Port 2)
l = lined g+2 (it's 1, 2 or 3)
p = points (downrace expansion)
q = quidditch snitch (ring bonus)
r = route (Joystick 2 direction)
s = skill (chosen path width)
t = toggle (one bit 1)
v = visual effects

Line 0:
Sound volume & waveform is initialised here and a loop starts the common screen color flickering
leaving the variables i=65 und t=1 for later use. The user is also asked to enter the skill level
as an integer number to s (of course I could've used s% here, but now you can provoke bugs :P)

Line 1:
Joystick Port 2 value as k, cursor poking to the last row with the start value f, and the path
width is defined in variables a and c, depending on skill level s eventually.
Then the main loop starts incrementing p (aka points) from zero (just a dot . because that's the
fastest way to insert a 0 in BASIC!) to k (just using 'any' high number; e would also work here)
Now we branch out to three seperate lines with an ON..GOTO that depends on trajectory g (-1/0/1)

Line 2 or 3 or 4:
The path is printed here (in yellow) related to the direction it goes, using special PETSCII chars
from keys UK, JI or >WQ<. Those prints end with different colors for the spiders (42 asterisks)
or .. and this is a new feature just for the 10-Liner version .. for some green rings (87 curl)!
Those are randomly poked on the screen (last row = f+) and growth g also gets a new random value.
--Side note: Even it takes more space these operations turned out to be faster than the classic
  way from the original (see above) with f=rnd(.)*39:g=int(f/13-1), but performance before size!
The t=1 is used here instead of the value 1 for the same reason! Turned out, this is MUCH faster.
After that, I had to find a way to convert the ifa+g=0orc+g=38theng=0 into a numeric expression
with operators. The result: g=g-(-g=a)+(c+g=38) <-- can be used partial based on the forelast g
This partial use left some space for v=53272 und d=214 that will be necessary later on.

Line 5:
This may contain some innovations for the 10-Liner community regarding joystick detection <->v
The line represents the central control assembly of this program. All the others might just be
"Klickibunti" stuff :) It includes almost all variables and tweaks for a better performance and
was alternated many many times to gain the most perfect result at last (hopefully).
First, the new path direction is computed for the borders a and c, then the Joystick 2 value is
stored in variable r as a decimal value with difference 120 (default is 127). Directly afterwards
the sled position b is incremented or decremented by 1 depending on the Joystick input left or
right -or- down/up or fire (on a gamepad for example) as an alternative with the same step.
Instantly after that, the new sled position b is checked to be free space (=32) and -if true- a
SID sound sizzle is created together with colouring that spot in orange/brown/grey and the sled
itself (i=65), going directly for the next loop round and round and round and so on..

Line 6:
This whole line was a bonus line I deserved for lots of space optimizations in the process of
converting this game into a 10-liner. I decided to place the free BONUS line right here for a
BONUS feature! Now I had all the time (and space) in the world to put some nice screen effects
and other gimmicks in there. Recently I found things like poke53265,59 or poke53272,96 but
please don't try this at home :)
After IF-checking we may hit a green bonus ring (=87), the SID should rise high for a moment
and the screen will show some strange characters (the Eye of Sauron!). Additionally the screen
border would flicker, 9 points are added to the score, an extra obstacle heart is placed nearby
and the screen border color changes randomly. The sleigh is also replaced by an @ sign .. NEXT

Line 7:
Whenever we've reached this line, our highly-valued wizard crashed unfortunately!
So a little PETSCII explosion is shown at that spot on the screen, followed by a loop that does
both a screen shattering and an explosion sound right away. The NEXT statement of this loop is
placed in the following line on purpose (you'll see why in the Line 9 description).

Line 8:
The score is printed and the bonus rings are zeroized. Then a part of the screen is filled up
with artistic game-over messages placed at spot h (for hate) by a loop to infinity (or k again).
The color of that logo is defined as "h+h" for two reasons: First, this is faster than "2*h" in
BASIC and second, we don't get the same color in the same line or row this way again and again.
The POKE and WAIT in 162 just creates a small delay of 8 jiffies here.

Line 9:
The game-over artwork is printed and the next new row it will appear is poked afterwards(!)
This is necessary because otherwise we would have a line of cleanly arranged logos instead of
randomly multicolored spots we indeed like to have anywhere on the screen.
This would continue forever until the firebutton is pressed. By converting this IF..THEN into
an ON..GOTO I was forced to jump back into a line, but I don't want to print the scores again
and again, so I placed the loop in the middle of line 8 and the NEXT from line 7 in the front.
So now, when I jump to line 8, it will "next" my loop in the middle of line 8! I know this is
a mortal sin for developers, but those 10-Liner rules forced me to do it so .. so, sorry :)
Otherwise we print an invers-heart aka CLR-screen and jump back to line 1. And there's always
space left for a small comment directly after GOTO ^_^


### Possible Expansions beyond the 10-Line Border:
=====================================================
1) A great PETSCII-Art from Radagast & Dol Guldur in the background at the start
2) More Bonus-Items beside the rings to get more speed/power/control/whatever..
3) Creating sprites for Radagast, his sleigh, the bunnies, the road, the items
4) More sound effects when a Bonus-Item is picked up or within game-over screen
5) Two-Player mode with splitscreen and special Bonus-Items for a challenge
